<!DOCTYPE html>
<html lang="en-us" dir="ltr" itemscope itemtype="http://schema.org/Article" data-r-output-format="html">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="height=device-height, width=device-width, initial-scale=1.0, minimum-scale=1.0">
    <meta name="generator" content="Hugo 0.147.3">
    <meta name="generator" content="Relearn 8.2.0+220806ce3ced8264fbdd693f77f28216a8a1b6ae">
    <meta name="description" content="gokrazy’s goal is to make it easy to build Go appliances. In an ideal world, all building blocks you need would be available in Go. In reality, that is not entirely the case. Perhaps you need to run a C program next to your Go programs. Docker containers make incremental (or partial) adoption of gokrazy easy.
We’re going to use podman, a drop-in replacement for Docker, because there is a statically compiled version for amd64 and arm64 available that we could easily re-package into https://github.com/gokrazy/podman.">
    <meta name="author" content="">
    <meta name="twitter:card" content="summary">
    <meta name="twitter:title" content="Docker containers :: gokrazy">
    <meta name="twitter:description" content="gokrazy’s goal is to make it easy to build Go appliances. In an ideal world, all building blocks you need would be available in Go. In reality, that is not entirely the case. Perhaps you need to run a C program next to your Go programs. Docker containers make incremental (or partial) adoption of gokrazy easy.
We’re going to use podman, a drop-in replacement for Docker, because there is a statically compiled version for amd64 and arm64 available that we could easily re-package into https://github.com/gokrazy/podman.">
    <meta property="og:url" content="https://gokrazy.org/packages/docker-containers/index.html">
    <meta property="og:site_name" content="gokrazy">
    <meta property="og:title" content="Docker containers :: gokrazy">
    <meta property="og:description" content="gokrazy’s goal is to make it easy to build Go appliances. In an ideal world, all building blocks you need would be available in Go. In reality, that is not entirely the case. Perhaps you need to run a C program next to your Go programs. Docker containers make incremental (or partial) adoption of gokrazy easy.
We’re going to use podman, a drop-in replacement for Docker, because there is a statically compiled version for amd64 and arm64 available that we could easily re-package into https://github.com/gokrazy/podman.">
    <meta property="og:locale" content="en_us">
    <meta property="og:type" content="article">
    <meta property="article:section" content="Available packages">
    <meta itemprop="name" content="Docker containers :: gokrazy">
    <meta itemprop="description" content="gokrazy’s goal is to make it easy to build Go appliances. In an ideal world, all building blocks you need would be available in Go. In reality, that is not entirely the case. Perhaps you need to run a C program next to your Go programs. Docker containers make incremental (or partial) adoption of gokrazy easy.
We’re going to use podman, a drop-in replacement for Docker, because there is a statically compiled version for amd64 and arm64 available that we could easily re-package into https://github.com/gokrazy/podman.">
    <meta itemprop="wordCount" content="605">
    <title>Docker containers :: gokrazy</title>
    <link href="/images/favicon.png?1763621646" rel="icon" type="image/png">
    <link href="/css/auto-complete/auto-complete.min.css?1763621646" rel="stylesheet">
    <script src="/js/auto-complete/auto-complete.min.js?1763621646" defer></script>
    <script src="/js/search-lunr.min.js?1763621646" defer></script>
    <script src="/js/search.min.js?1763621646" defer></script>
    <script>
      window.relearn = window.relearn || {};
      window.relearn.index_js_url="/searchindex.en.js?1763621646";
    </script>
    <script src="/js/lunr/lunr.min.js?1763621646" defer></script>
    <script src="/js/lunr/lunr.stemmer.support.min.js?1763621646" defer></script>
    <script src="/js/lunr/lunr.multi.min.js?1763621646" defer></script>
    <script src="/js/lunr/lunr.en.min.js?1763621646" defer></script>
    <script>
      window.relearn = window.relearn || {};
      window.relearn.contentLangs=['en'];
    </script>
    <link href="/fonts/fontawesome/css/fontawesome-all.min.css?1763621646" rel="stylesheet" media="print" onload="this.media='all';this.onload=null;"><noscript><link href="/fonts/fontawesome/css/fontawesome-all.min.css?1763621646" rel="stylesheet"></noscript>
    <link href="/css/perfect-scrollbar/perfect-scrollbar.min.css?1763621646" rel="stylesheet">
    <link href="/css/theme.min.css?1763621646" rel="stylesheet">
    <link href="/css/format-html.min.css?1763621646" rel="stylesheet" id="R-format-style">
    <script>
      window.relearn = window.relearn || {};
      // configuration
      window.relearn.min = `.min`;
      window.relearn.path='\/packages\/docker-containers\/index.html';
      window.relearn.relBasePath='..\/..';
      window.relearn.relBaseUri='..\/..';
      window.relearn.absBaseUri='https:\/\/gokrazy.org';
      window.relearn.disableInlineCopyToClipboard=true;
      window.relearn.enableBlockCodeWrap=true;
      // legal
      window.relearn.getItem = (s,n) => {return s.getItem(n)};
      window.relearn.setItem = (s,n,v) => {return s.setItem(n,v)};
      window.relearn.removeItem = (s,n) => {return s.removeItem(n)};
      // translations
      window.T_Copy_to_clipboard = `Copy text to clipboard`;
      window.T_Copied_to_clipboard = `Text copied to clipboard!`;
      window.T_Link_copied_to_clipboard = `Link copied to clipboard!`;
      window.T_Reset_view = `Reset view`;
      window.T_View_reset = `View reset!`;
      window.T_No_results_found = `No results found for "{0}"`;
      window.T_N_results_found = `{1} results found for "{0}"`;
      window.T_Browser_unsupported_feature = `This browser doesn't support this feature`;
      // variant stuff
      window.relearn.themevariants = [ 'auto' ];
      window.relearn.customvariantname = "my-custom-variant";
      window.relearn.changeVariant = function(variant) {
        var oldVariant = document.documentElement.dataset.rThemeVariant;
        window.relearn.setItem(window.localStorage, window.relearn.absBaseUri + "/variant", variant);
        document.documentElement.dataset.rThemeVariant = variant;
        if (oldVariant != variant) {
          document.dispatchEvent( new CustomEvent('themeVariantLoaded', { detail: { variant, oldVariant } }) );
          window.relearn.markVariant();
        }
      }
      window.relearn.markVariant = function() {
        var variant = window.relearn.getItem(window.localStorage, window.relearn.absBaseUri + "/variant");
        document.querySelectorAll(".R-variantswitcher select").forEach((select) => {select.value = variant;});
      }
      window.relearn.initVariant = function() {
        var variant = window.relearn.getItem(window.localStorage, window.relearn.absBaseUri + "/variant") ?? "";
        if( variant == window.relearn.customvariantname ){
        }else if( !variant || !window.relearn.themevariants.includes(variant) ){
          variant = window.relearn.themevariants[0];
          window.relearn.setItem(window.localStorage, window.relearn.absBaseUri + "/variant", variant);
        }
        document.documentElement.dataset.rThemeVariant = variant;
      }
      window.relearn.initVariant();
      window.relearn.markVariant();
    </script>
  </head>
  <body class="mobile-support html" data-url="/packages/docker-containers/index.html">
    <div id="R-body" class="default-animation">
      <div id="R-body-overlay"></div>
      <nav id="R-topbar">
        <div class="topbar-wrapper">
          <div class="topbar-sidebar-divider"></div>
          <div class="topbar-area topbar-area-start" data-area="start">
            <div class="topbar-button topbar-button-sidebar" data-content-empty="disable" data-width-s="show" data-width-m="hide" data-width-l="hide">
<span class="btn cstyle button link noborder notitle interactive"><button onclick="toggleNav()" type="button" title="Menu (CTRL&#43;ALT&#43;n)"><i class="fa-fw fas fa-bars"></i></button></span>
            </div>
            <div class="topbar-button topbar-button-toc" data-content-empty="hide" data-width-s="show" data-width-m="show" data-width-l="show">
<span class="btn cstyle button link noborder notitle interactive"><button onclick="toggleTopbarFlyout(this)" type="button" title="Table of Contents (CTRL&#43;ALT&#43;t)"><i class="fa-fw fas fa-list-alt"></i></button></span>
              <div class="topbar-content">
                <div class="topbar-content-wrapper">
<nav class="TableOfContents">
  <ul>
    <li><a href="#step-1-install-podman-to-your-gokrazy-device">Step 1: Install podman to your gokrazy device</a></li>
    <li><a href="#step-2-verify-podman-works">Step 2: Verify podman works</a></li>
    <li><a href="#step-3-use-podman-programmatically">Step 3: Use podman programmatically</a></li>
  </ul>
</nav>
                </div>
              </div>
            </div>
          </div>
          <ol class="topbar-breadcrumbs breadcrumbs highlightable" itemscope itemtype="http://schema.org/BreadcrumbList"><li itemscope itemtype="https://schema.org/ListItem" itemprop="itemListElement" class=""><a itemprop="item" href="/index.html"><span itemprop="name">gokrazy Go appliances</span></a><meta itemprop="position" content="1">&nbsp;>&nbsp;</li><li itemscope itemtype="https://schema.org/ListItem" itemprop="itemListElement" class=""><a itemprop="item" href="/packages/index.html"><span itemprop="name">Available packages</span></a><meta itemprop="position" content="2">&nbsp;>&nbsp;</li><li itemscope itemtype="https://schema.org/ListItem" itemprop="itemListElement" class=""><span itemprop="name">Docker containers</span><meta itemprop="position" content="3"></li>
          </ol>
          <div class="topbar-area topbar-area-end" data-area="end">
            <div class="topbar-button topbar-button-edit" data-content-empty="disable" data-width-s="area-more" data-width-m="show" data-width-l="show">
<span class="btn cstyle button link noborder notitle interactive"><a href="https://github.com/gokrazy/gokrazy/tree/master/website/content/packages/docker-containers.markdown" rel="external" title="Edit (CTRL+ALT+w)"><i class="fa-fw fas fa-pen"></i></a></span>
            </div>
            <div class="topbar-button topbar-button-more" data-content-empty="hide" data-width-s="show" data-width-m="show" data-width-l="show">
<span class="btn cstyle button link noborder notitle interactive"><button onclick="toggleTopbarFlyout(this)" type="button" title="More"><i class="fa-fw fas fa-ellipsis-v"></i></button></span>
              <div class="topbar-content">
                <div class="topbar-content-wrapper">
                  <div class="topbar-area topbar-area-more" data-area="more">
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </nav>
      <div id="R-main-overlay"></div>
      <main id="R-body-inner" class="highlightable packages" tabindex="-1">
        <div class="flex-block-wrapper">
<article class="default">
  <header class="headline">
  </header>

<h1 id="docker-containers">Docker containers</h1>

<p>gokrazy’s goal is to make it easy to build Go appliances. In an ideal world, all
building blocks you need would be available in Go. In reality, that is not
entirely the case. Perhaps you need to run a C program next to your Go
programs. Docker containers make incremental (or partial) adoption of gokrazy
easy.</p>
<p>We’re going to use podman, a drop-in replacement for Docker, because there is a
statically compiled version for amd64 and arm64 available that we could easily
re-package into <a href="https://github.com/gokrazy/podman" rel="external">https://github.com/gokrazy/podman</a>.</p>
<h2 id="step-1-install-podman-to-your-gokrazy-device">Step 1: Install podman to your gokrazy device<span class="btn cstyle anchor copyanchor scrollanchor link noborder notitle interactive"><button type="button" title="Copy link to clipboard"><i class="fa-fw fas fa-link fa-lg"></i></button></span></h2>
<p>Include the following packages in your gokrazy installation:</p>
<div class="highlight actionbar-wrapper wrap-code" dir="auto"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>gok add github.com/gokrazy/iptables
</span></span><span style="display:flex;"><span>gok add github.com/gokrazy/nsenter
</span></span><span style="display:flex;"><span>gok add github.com/gokrazy/podman
</span></span><span style="display:flex;"><span>gok add github.com/greenpau/cni-plugins/cmd/cni-nftables-portmap
</span></span><span style="display:flex;"><span>gok add github.com/greenpau/cni-plugins/cmd/cni-nftables-firewall</span></span></code></pre></div>
<p>Then, deploy as usual:</p>
<div class="highlight actionbar-wrapper wrap-code" dir="auto"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>gok update</span></span></code></pre></div>
<h2 id="step-2-verify-podman-works">Step 2: Verify podman works<span class="btn cstyle anchor copyanchor scrollanchor link noborder notitle interactive"><button type="button" title="Copy link to clipboard"><i class="fa-fw fas fa-link fa-lg"></i></button></span></h2>
<p>Use <a href="https://github.com/gokrazy/breakglass" rel="external">breakglass</a> to login to your gokrazy
instance and run a container manually:</p>
<div class="highlight actionbar-wrapper wrap-code" dir="auto"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>/tmp/breakglass187145741 $ podman run --rm -ti docker.io/library/debian:sid
</span></span><span style="display:flex;"><span>root@gokrazy:/# cat /etc/debian_version
</span></span><span style="display:flex;"><span>12.0</span></span></code></pre></div>
<h2 id="step-3-use-podman-programmatically">Step 3: Use podman programmatically<span class="btn cstyle anchor copyanchor scrollanchor link noborder notitle interactive"><button type="button" title="Copy link to clipboard"><i class="fa-fw fas fa-link fa-lg"></i></button></span></h2>
<p>Now that you have the required tools, there are a couple of decisions you have
to make depending on what you want to run in your container(s):</p>
<ol>
<li>Should container data be stored ephemerally in <code>tmpfs</code> (lost with the next
reboot), on the permanent partition of your SD card, or somewhere else
entirely (e.g. network storage)?</li>
<li>Do you want to pull new container versions automatically before each run, or
manually on demand only?</li>
<li>Should your container be started as a one-off job only (<a href="https://docs.docker.com/engine/reference/run/#detached--d" rel="external">→ detached
mode</a>), or
supervised continuously (restarted when it exits)?</li>
<li>Should your container use a deterministic name (so that you can <code>exec</code>
commands in it easily), or use a fresh name for each run (so that there never
are conflicts)?</li>
</ol>
<p>Aside from these broad questions, you very likely need to set a bunch of detail
options for your container, such as additional environment variables, volume
mounts, networking flags, or command line arguments.</p>
<p>The following program is an example for how this could look like. I use this
program to run <a href="https://irssi.org/" rel="external">irssi</a>.</p>
<div class="highlight actionbar-wrapper wrap-code" dir="auto"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">main</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> (
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;fmt&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;log&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;os&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;os/exec&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;strings&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;github.com/gokrazy/gokrazy&#34;</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">podman</span>(<span style="color:#a6e22e">args</span> <span style="color:#f92672">...</span><span style="color:#66d9ef">string</span>) <span style="color:#66d9ef">error</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">podman</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">exec</span>.<span style="color:#a6e22e">Command</span>(<span style="color:#e6db74">&#34;/usr/local/bin/podman&#34;</span>, <span style="color:#a6e22e">args</span><span style="color:#f92672">...</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">podman</span>.<span style="color:#a6e22e">Env</span> = <span style="color:#a6e22e">expandPath</span>(<span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">Environ</span>())
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">podman</span>.<span style="color:#a6e22e">Env</span> = append(<span style="color:#a6e22e">podman</span>.<span style="color:#a6e22e">Env</span>, <span style="color:#e6db74">&#34;TMPDIR=/tmp&#34;</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">podman</span>.<span style="color:#a6e22e">Stdin</span> = <span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">Stdin</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">podman</span>.<span style="color:#a6e22e">Stdout</span> = <span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">Stdout</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">podman</span>.<span style="color:#a6e22e">Stderr</span> = <span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">Stderr</span>
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">podman</span>.<span style="color:#a6e22e">Run</span>(); <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;%v: %v&#34;</span>, <span style="color:#a6e22e">podman</span>.<span style="color:#a6e22e">Args</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">irssi</span>() <span style="color:#66d9ef">error</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// Ensure we have an up-to-date clock, which in turn also means that</span>
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// networking is up. This is relevant because podman takes what’s in</span>
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// /etc/resolv.conf (nothing at boot) and holds on to it, meaning your</span>
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// container will never have working networking if it starts too early.</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">gokrazy</span>.<span style="color:#a6e22e">WaitForClock</span>()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">podman</span>(<span style="color:#e6db74">&#34;kill&#34;</span>, <span style="color:#e6db74">&#34;irssi&#34;</span>); <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">log</span>.<span style="color:#a6e22e">Print</span>(<span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">podman</span>(<span style="color:#e6db74">&#34;rm&#34;</span>, <span style="color:#e6db74">&#34;irssi&#34;</span>); <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">log</span>.<span style="color:#a6e22e">Print</span>(<span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// You could podman pull here.</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">podman</span>(<span style="color:#e6db74">&#34;run&#34;</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#e6db74">&#34;-td&#34;</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#e6db74">&#34;-v&#34;</span>, <span style="color:#e6db74">&#34;/perm/irssi:/home/michael/.irssi&#34;</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#e6db74">&#34;-v&#34;</span>, <span style="color:#e6db74">&#34;/perm/irclogs:/home/michael/irclogs&#34;</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#e6db74">&#34;-e&#34;</span>, <span style="color:#e6db74">&#34;TERM=rxvt-unicode&#34;</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#e6db74">&#34;-e&#34;</span>, <span style="color:#e6db74">&#34;LANG=C.UTF-8&#34;</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#e6db74">&#34;--network&#34;</span>, <span style="color:#e6db74">&#34;host&#34;</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#e6db74">&#34;--name&#34;</span>, <span style="color:#e6db74">&#34;irssi&#34;</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#e6db74">&#34;docker.io/stapelberg/irssi:latest&#34;</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#e6db74">&#34;screen&#34;</span>, <span style="color:#e6db74">&#34;-S&#34;</span>, <span style="color:#e6db74">&#34;irssi&#34;</span>, <span style="color:#e6db74">&#34;irssi&#34;</span>); <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">err</span>
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">irssi</span>(); <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">log</span>.<span style="color:#a6e22e">Fatal</span>(<span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// expandPath returns env, but with PATH= modified or added</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// such that both /user and /usr/local/bin are included, which podman needs.</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">expandPath</span>(<span style="color:#a6e22e">env</span> []<span style="color:#66d9ef">string</span>) []<span style="color:#66d9ef">string</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">extra</span> <span style="color:#f92672">:=</span> <span style="color:#e6db74">&#34;/user:/usr/local/bin&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">found</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">idx</span>, <span style="color:#a6e22e">val</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">env</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">parts</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">strings</span>.<span style="color:#a6e22e">Split</span>(<span style="color:#a6e22e">val</span>, <span style="color:#e6db74">&#34;=&#34;</span>)
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">if</span> len(<span style="color:#a6e22e">parts</span>) &lt; <span style="color:#ae81ff">2</span> {
</span></span><span style="display:flex;"><span>			<span style="color:#66d9ef">continue</span> <span style="color:#75715e">// malformed entry</span>
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">key</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">parts</span>[<span style="color:#ae81ff">0</span>]
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">key</span> <span style="color:#f92672">!=</span> <span style="color:#e6db74">&#34;PATH&#34;</span> {
</span></span><span style="display:flex;"><span>			<span style="color:#66d9ef">continue</span>
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">val</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">strings</span>.<span style="color:#a6e22e">Join</span>(<span style="color:#a6e22e">parts</span>[<span style="color:#ae81ff">1</span>:], <span style="color:#e6db74">&#34;=&#34;</span>)
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">env</span>[<span style="color:#a6e22e">idx</span>] = <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Sprintf</span>(<span style="color:#e6db74">&#34;%s=%s:%s&#34;</span>, <span style="color:#a6e22e">key</span>, <span style="color:#a6e22e">extra</span>, <span style="color:#a6e22e">val</span>)
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">found</span> = <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> !<span style="color:#a6e22e">found</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">busyboxDefaultPATH</span> = <span style="color:#e6db74">&#34;/usr/local/sbin:/sbin:/usr/sbin:/usr/local/bin:/bin:/usr/bin&#34;</span>
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">env</span> = append(<span style="color:#a6e22e">env</span>, <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Sprintf</span>(<span style="color:#e6db74">&#34;PATH=%s:%s&#34;</span>, <span style="color:#a6e22e">extra</span>, <span style="color:#a6e22e">busyboxDefaultPATH</span>))
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">env</span>
</span></span><span style="display:flex;"><span>}</span></span></code></pre></div>

  <footer class="footline">
  </footer>
</article>
        </div>
      </main>
    </div>
    <aside id="R-sidebar" class="default-animation">
      <div id="R-header-topbar" class="default-animation"></div>
      <div id="R-header-wrapper" class="default-animation">
        <div id="R-header" class="default-animation">
<img src="/logo.svg" width="100%" alt="gokrazy logo" title="gokrazy logo">

        </div>
        <search><form action="/search/index.html" method="get">
          <div class="searchbox default-animation">
            <button class="search-detail" type="submit" title="Search (CTRL+ALT+f)"><i class="fas fa-search"></i></button>
            <label class="a11y-only" for="R-search-by">Search</label>
            <input data-search-input id="R-search-by" name="search-by" class="search-by" type="search" placeholder="Search...">
            <button class="search-clear" type="button" data-search-clear="" title="Clear search"><i class="fas fa-times" title="Clear search"></i></button>
          </div>
        </form></search>
      </div>
      <div id="R-homelinks" class="default-animation homelinks">
        <div class="R-menu-divider default-animation">
          <hr class="padding">
        </div>
        <div class="R-sidebarmenu R-shortcutmenu-homelinks">
          <ul class="space collapsible-menu">
            <li class="" data-nav-url="/index.html"><a class="padding" href="/index.html"><i class="fa-fw fas fa-home"></i> Home</a></li>
          </ul>
        </div>
        <div class="R-menu-divider default-animation">
          <hr class="padding">
        </div>
        <div class="R-sidebarmenu R-shortcutmenu-headercontrols">
          <ul class="">
          </ul>
        </div>
        <div class="R-menu-divider default-animation">
          <hr class="padding">
        </div>
      </div>
      <div id="R-content-wrapper" class="highlightable">
        <div class="R-sidebarmenu R-shortcutmenu-main">
          <ul class="enlarge morespace collapsible-menu">
            <li class="" data-nav-url="/quickstart/index.html"><a class="padding" href="/quickstart/index.html"><b>1. </b>Quickstart</a></li>
            <li class="" data-nav-url="/platforms/index.html"><a class="padding" href="/platforms/index.html"><b>2. </b>Supported platforms</a></li>
            <li class="" data-nav-url="/userguide/index.html"><a class="padding" href="/userguide/index.html"><b>3. </b>Configuration</a><ul id="R-subsections-74b4df3a3d9365853f09e9f1dfe7bbba" class="collapsible-menu"></ul></li>
            <li class="parent " data-nav-url="/packages/index.html"><a class="padding" href="/packages/index.html"><b>4. </b>Available packages</a><ul id="R-subsections-bdf1e8ce92aa8ff6883c617f10480430" class="collapsible-menu">
            <li class="" data-nav-url="/packages/showcase/index.html"><a class="padding" href="/packages/showcase/index.html">Showcase</a></li>
            <li class="" data-nav-url="/packages/tailscale/index.html"><a class="padding" href="/packages/tailscale/index.html">Tailscale VPN</a></li>
            <li class="" data-nav-url="/packages/caddy-http-server/index.html"><a class="padding" href="/packages/caddy-http-server/index.html">Caddy HTTP server</a></li>
            <li class="" data-nav-url="/packages/minio/index.html"><a class="padding" href="/packages/minio/index.html">MinIO object storage</a></li>
            <li class="active " data-nav-url="/packages/docker-containers/index.html"><a class="padding" href="/packages/docker-containers/index.html">Docker containers</a></li>
            <li class="" data-nav-url="/packages/prometheus/index.html"><a class="padding" href="/packages/prometheus/index.html">Prometheus</a></li></ul></li>
            <li class="" data-nav-url="/development/index.html"><a class="padding" href="/development/index.html"><b>5. </b>Package development</a><ul id="R-subsections-54b0ce3c97b111c8cd4d107325fd580c" class="collapsible-menu"></ul></li>
          </ul>
        </div>
        <div class="R-sidebarmenu R-shortcutmenu-shortcuts">
          <div class="nav-title padding">More</div>
          <ul class="space collapsible-menu">
            <li class="" data-nav-url="https://github.com/gokrazy/gokrazy"><a class="padding" href="https://github.com/gokrazy/gokrazy" rel="external"><i class='fab fa-github'></i> GitHub repo</a></li>
          </ul>
        </div>
        <div id="R-footer-margin"></div>
        <div class="R-menu-divider default-animation">
          <hr class="padding">
        </div>
        <div class="R-sidebarmenu R-shortcutmenu-footercontrols">
          <ul class="">
          </ul>
        </div>
<div id="R-footer"><p>Built with <a href="https://github.com/McShelby/hugo-theme-relearn" title="love"><i class="fas fa-heart"></i></a> by <a href="https://gohugo.io/">Hugo</a></p></div>
      </div>
    </aside>
    <script src="/js/perfect-scrollbar/perfect-scrollbar.min.js?1763621646" defer></script>
    <script src="/js/theme.min.js?1763621646" defer></script>
    <div id="toast-container" role="status" aria-live="polite" aria-atomic="false"></div>
  </body>
</html>
